package com.jlect.swebing.ui.laf.basic.client;

import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.ui.AbsolutePanel;
import com.google.gwt.user.client.ui.Panel;
import com.google.gwt.user.client.ui.Widget;
import com.jlect.swebing.ui.client.Dimension;
import com.jlect.swebing.ui.client.GComponent;
import com.jlect.swebing.ui.client.GContainer;
import com.jlect.swebing.ui.client.PropertyChangeEvent;
import com.jlect.swebing.ui.client.laf.ComponentUI;
import com.jlect.swebing.ui.client.laf.ContainerUI;

/**
 * Container UI delegate default implementation
 *
 * @author Sergey Kozmin
 * @since 05.12.2007 10:21:34
 */
public class BasicContainerUI extends AbstractComponentUI implements ContainerUI {
    public ComponentUI createInstance() {
        return new BasicContainerUI();
    }

    protected GContainer getComponent() {
        return (GContainer) super.getComponent();
    }

    public Dimension getPreferredSize() {
        return new Dimension(120, 120);//@todo return sum of preffered components sizes
    }

    public Dimension getMaximumSize() {
        return Dimension.MAX_SIZE_DIMENSION;
    }

    public Dimension getMinimumSize() {
        return Dimension.ZERO_SIZE_DIMENSION;  //@todo return sum of min components sizes
    }

    protected Widget provideWidget() {
        return new CompositeAttachEventProvider(new AbsolutePanel());
    }

    public void propertyChange(PropertyChangeEvent evt) {
        if(GContainer.COMPONENT_ADDED_PROPERTY_NAME.equalsIgnoreCase(evt.getPropertyName())) {//todo optimize
            GComponent child = (GComponent) evt.getNewValue();
            addElement(child.getUI());
        } else if(GContainer.COMPONENT_REMOVED_PROPERTY_NAME.equalsIgnoreCase(evt.getPropertyName())) {//todo optimize
            GComponent child = (GComponent) evt.getNewValue();
            removeElement(child.getUI());
        } else {
            super.propertyChange(evt);
        }
    }

    public void addElement(ComponentUI child) {
        getPanel().add(checkIfAcceptable(child).getWidget());
    }

    public void removeElement(ComponentUI child) {
        getPanel().remove(checkIfAcceptable(child).getWidget());
    }

    private WidgetProvider checkIfAcceptable(ComponentUI proving) {
        if(!(proving instanceof WidgetProvider)) {
            throw new IllegalArgumentException("Could not work with components that is not a [WidgetProvider] class," +
                    " the given component has class [" + GWT.getTypeName(proving) + "]. ");
        } else {
            return (WidgetProvider) proving;
        }
    }

    protected Panel getPanel() {
        return (Panel) ((CompositeAttachEventProvider)getWidget()).getTargetWidget();
    }
}
